<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Tokenwallet;
use app\common\model\Trade as TradeModel;
use app\common\model\trade\Log as Tradelog;
use app\common\model\User;
use app\common\model\Bank;
use fast\Random;
use think\Hook;


/**
 * 数字交易
 */
class Trade extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = [''];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = '*';


    public function _initialize()
    {
        parent::_initialize();
        $auth = $this->auth;
        Hook::add('check_paypwd', function ($paypwd) use ($auth) {
            if ($auth->getUser()['payplaintext'] != $paypwd) {
                $this->error('安全密码不正确');
            }
        });

        Hook::add('check_pay', function ($pay) use ($auth) {
            $user = $auth->getUser();
            switch ($pay) {
                case 'alipay':
                    if (empty($user->alipay)) {
                        $this->error('未完善支付宝信息');
                    }
                    break;
                case 'wechatwallet':
                    if (empty($user->wechatwallet)) {
                        $this->error('未完善微信信息');
                    }
                    break;
                case 'bank':
                    $bank = new Bank();
                    $banks=$bank->where('status',1)->where('default',1)->where('user_id',$auth->id)->order('default desc,id desc')->find();
                    if (empty($banks)) {
                        $this->error('未完善银行卡信息');
                    }
                    break;
                case 'eth':
                    if (empty($user->eth)) {
                        $this->error('未完善钱包地址信息');
                    }
                    break;
                case 'mobile':
                        if (empty($user->mobile)) {
                            $this->error('未完善电话信息');
                        }
                        break;
                case 'email':
                    if (empty($user->email)) {
                        $this->error('未完善邮箱信息');
                    }
                    break;
                default:
                    $this->error('收付款信息错误');
                    break;
            }
        });

        Hook::add('get_userpay',function($user_id){
            // $user = $auth->getUser();
            $user = User::get($user_id);
            // var_dump($user);
            $pay['alipay']='';
            $pay['wechatwallet']='';
            $pay['banks']='';
            $pay['eth']='';
            $pay['mobile']='';
            if (!empty($user->alipay)) {
                $pay['alipay'] = $user->alipay;
            }
            if (!empty($user->wechatwallet)) {
                $pay['wechatwallet'] = $user->wechatwallet;
            }
            if (!empty($user->eth)) {
                $pay['eth'] = $user->eth;
            }
            if (!empty($user->mobile)) {
                $pay['mobile'] = $user->mobile;
            }

            $bank = new Bank();
            $banks=$bank->where('status',1)->where('user_id',$user_id)->where('default',1)->find();

            if (!empty($banks)) {
                $pay['banks'] = $banks;
            }
            return $pay;
        });
    }



    /**
     * 初始化交易信息
     * @return [type] [description]
     */
    public function init()
    {
        // $list = db('coin')->field('id,name,symbol,exch_rate,describe')->select();
        $main = db('coin')->where('symbol','USD')->field('id,name,symbol,exch_rate,exch_rate_usd,describe')->find();
        $other = db('coin')->where('symbol','FAE')->field('id,name,symbol,exch_rate,exch_rate_usd,describe')->select();
        $trade_out_poundage = config('site.trade_out_poundage');
        $trade_in_poundage = config('site.trade_in_poundage');
        $this->success('返回成功',['main'=>$main,'other'=>$other,'trade_out_poundage'=>$trade_out_poundage,'trade_in_poundage'=>$trade_in_poundage]);
    }

    /**
     * 获取数字钱包信息
     * @return [type] [description]
     */
    public function getWallet()
    {
        $token = $this->auth->getUserToken();
        $this->success('返回成功',['info'=>$token]);
    }

    /**
     * 卖出
     * @param int $symbol 货币
     * @param int $tosymbol 货币
     * @param int $num 数量
     * @return [type] [description]
     */
    public function sell()
    {
        $request = $this->request->request();

        $paypwd = $this->request->request('paypwd','');
        Hook::listen("check_paypwd",$paypwd);
        // Hook::listen('check_pay',$request['pay']);//检查收款信息


        $symbol = $request['symbol'];
        $tosymbol = $request['tosymbol'];

        try {
            $token = $this->auth->getUserToken()[$symbol];
        } catch (\Exception $e) {
            $token = 0;
        }
        if (empty($request['num'])) {
            $this->error('未传入数量');
        }
        if ($token < $request['num']) {
            $this->error($symbol.'币不足');
        }

        if ($request['tosymbol'] == 'USDT' && $request['symbol'] != 'USD') {
            $this->error('只有Y币能够挂卖USDT');
        }

        $trade_in_min = config('site.trade_in_min');
        $trade_in_multiple = config('site.trade_in_multiple');
        if ($trade_in_min > $request['num']) {
            $this->error(__('不能少于'.$trade_in_min));
        }

        if ($request['num'] % $trade_in_multiple != 0) {
            $this->error(__('请输入'.$trade_in_multiple.'的倍数'));
        }

        
        $main = db('coin')->where('symbol',$symbol)->field('id,name,symbol,exch_rate,describe')->find();
        $tomain = db('coin')->where('symbol',$tosymbol)->field('id,name,symbol,exch_rate,describe')->find();


        $trademodel = new TradeModel();
        // $user = $this->auth->getUser();
        $trademodel->action = 'sell'; 
        $trademodel->user_id = $this->auth->id;
        // $trademodel->exch_rate = 4; //TODO 计算汇率
        $trademodel->exch_rate = bcdiv($main['exch_rate'],$tomain['exch_rate'],2);
        // $trademodel->user_id = $user->id;

        $result = $trademodel->allowField(true)->validate('Trade.add')->save($request);
        if(false === $result){
            $this->error($trademodel->getError());
        }else{
            User::tokenlog($symbol,$this->auth->id,0,-$request['num'],'sell','卖出');
            $trade_in_poundage = config('site.trade_in_poundage');
            User::tokenlog($symbol,$this->auth->id,0,-$request['num']*bcdiv($trade_in_poundage, 100,3),'sell_poundage','卖出扣除手续费');

            // TODO user 静态方法 扣除钱包 并写入记录
        }

        $this->success('卖出成功',['token'=>$token,'sql'=>$trademodel->getLastSql()]);
    }


    /**
     * 买入
     * @param int $symbol 货币
     * @param int $tosymbol 货币
     * @param int $num 数量
     * @return [type] [description]
     */
    public function buy()
    {
        $request = $this->request->request();

        $paypwd = $this->request->request('paypwd','');
        Hook::listen("check_paypwd",$paypwd);
        // Hook::listen('check_pay',$request['pay']);//检查收款信息

        $symbol = $request['symbol'];
        $tosymbol = $request['tosymbol'];

        

        if ($symbol == 'USDT') {
            if ($request['tosymbol'] != 'USD') {
                $this->error('USDT只能够挂买Y币');
            }
        }else{
            try {
                $token = $this->auth->getUserToken()[$symbol];
            } catch (\Exception $e) {
                $token = 0;
            }
            
            if ($token < $request['num']) {
                $this->error($symbol.'不足');
            }
        }
        $trade_in_min = config('site.trade_in_min');
        $trade_in_multiple = config('site.trade_in_multiple');
        if ($trade_in_min > $request['num']) {
            $this->error(__('不能少于'.$trade_in_min));
        }

        if ($request['num'] % $trade_in_multiple != 0) {
            $this->error(__('请输入'.$trade_in_multiple.'的倍数'));
        }

        $main = db('coin')->where('symbol',$symbol)->field('id,name,symbol,exch_rate,describe')->find();
        $tomain = db('coin')->where('symbol',$tosymbol)->field('id,name,symbol,exch_rate,describe')->find();
        $trademodel = new TradeModel();
        $trademodel->action = 'buy'; 
        $trademodel->user_id = $this->auth->id;
        $trademodel->exch_rate = bcdiv($main['exch_rate'],$tomain['exch_rate'],2);
        $result = $trademodel->allowField(true)->validate('Trade.add')->save($request);
        if(false === $result){
            $this->error($trademodel->getError());
        }else{
            // User::tokenlog($symbol,$this->auth->id,0, -$request['num'],'buy','买入');
        }

        $this->success('委托买入成功',[]);
    }


    /**
     * 自己寻找挂买订单 主动将货币卖给买家 B TO B
     * @return [type] [description]
     */
    // public function selfsell()
    // {
    //     $id = $this->request->request('id/d');
    //     $num = $this->request->request('num/d');
    //     if (!$id) {
    //         $this->error('请传入ID');
    //     }
    //     if (!$num) {
    //         $this->error('请传入购买数量');
    //     }
        

    //     $trademodel = new TradeModel();
    //     $trade = $trademodel->where('user_id','<>',$this->auth->id)->where('surplusnum','>',0)->where('id',$id)->where('action','buy')->find();
    //     if (!$trade) {
    //         $this->error('没有找到该订单');
    //     }
    //     if (!in_array($trade['status'], [0,1])) {
    //         $this->error('订单已经被人抢先一步了！');
    //     }

    //     if ($num > $trade['surplusnum']) {
    //         $this->error('订单数量不足，请刷新重试');
    //     }

    //     try {
    //         $token = $this->auth->getUserToken()[$trade['symbol']];
    //     } catch (\Exception $e) {
    //         $token = 0;
    //     }
    //     $tradenum = bcmul($num, $trade['exch_rate']);
    //     if ($token < bcmul($num, $trade['exch_rate'])) {
    //         $this->error('您的货币不足 '.$trade['symbol']);
    //     }
    //     // TODO 减订单数量 增加token增加记录
    //     $trademodel->where('id',$trade->id)->dec('surplusnum',$num)->update(['status'=>1]);

    //     User::tokenlog($trade['symbol'],$this->auth->id,0,-$num,'sell','主动寻找买家卖出');
    //     $trade_in_poundage = config('site.trade_in_poundage');
    //     User::tokenlog($trade['symbol'],$this->auth->id,0,-$num*bcdiv($trade_in_poundage, 100,3),'sell_poundage','卖出扣除手续费');

    //     // TODO 写入交易日志
    //     $action = request()->action();
    //     $username = $this->auth->getUserinfo()['username'];
    //     Tradelog::Log(Random::tradeno(),$trade->user_id,$trade->user->username,$trade->id,$this->auth->id,$username,0,$num,$num,$tradenum,'finish',$action,$trade['symbol'],$trade['tosymbol']);
    //     $this->success('委托卖出成功',[]);
    // }

    /**
     * 自己寻找挂卖订单 使用 货币将另一种货币买下
     * symbol是买家卖出的 的货币  tosymbol 是卖家想要
     * @return [type] [description]
     */
    // public function selfbuy()
    // {
    //     $id = $this->request->request('id/d');
    //     $num = $this->request->request('num/d');
    //     if (!$id) {
    //         $this->error('请传入ID');
    //     }
    //     if (!$num) {
    //         $this->error('请传入卖出数量');
    //     }

    //     $trademodel = new TradeModel();
    //     $trade = $trademodel->where('user_id','<>',$this->auth->id)->where('surplusnum','>',0)->where('id',$id)->where('action','sell')->find();
    //     if (!$trade) {
    //         $this->error('没有找到该订单');
    //     }
    //     if (!in_array($trade['status'], [0,1])) {
    //         $this->error('订单已经被人抢先一步了！');
    //     }

    //     if ($num > $trade['surplusnum']) {
    //         $this->error('订单数量不足，请刷新重试');
    //     }

    //     try {
    //         $token = $this->auth->getUserToken()[$trade['tosymbol']];
    //     } catch (\Exception $e) {
    //         $token = 0;
    //     }

    //     $tradenum = bcmul($num, $trade['exch_rate'],2);
    //     if ($token < $tradenum) {
    //         $this->error('您的货币不足 '.$trade['symbol']);
    //     }

    //     $trademodel->where('id',$trade->id)->dec('surplusnum',$num)->update(['status'=>1]);
    //     User::tokenlog($trade['tosymbol'],$this->auth->id,0,$num,'buy','主动寻找卖家买出');

    //     $action = request()->action();
    //     $username = $this->auth->getUserinfo()['username'];
    //     Tradelog::Log(Random::tradeno(),$this->auth->id,$username,0,$trade->user_id,$trade->user->username,$trade->id,$num,$num,$tradenum,'finish',$action,$trade['symbol'],$trade['tosymbol']);
    //     $this->success('交易成功');
    // }

    /**
     * 我的交易 订单
     * @ApiParams   (name="action", type="string", required=true, description="买入卖出查询  buy  sell")
     * @ApiParams   (name="type", type="int", required=true, description="0=>等待中（未开始交易）,1=>进行中,2=>已完成，3=>撤销,4=>锁定中,5=>异常")
     * @ApiParams   (name="page", type="int", required=true, description="当前页数")
     * @return [type] [description]
     */
    public function orderlist()
    {
        $status = $this->request->request('status',0);
        $action = $this->request->request('action','');
        // if (!in_array($action, ['buy','sell','all'])) {
        //     $this->error('传值错误');
        // }
        // $where=[];
        // if ($action != 'all') {
        //     $where['action']=$action;
        // }
        // if ($status == -1) {
        //     $where['status']=['in',['0','1']];
        // }
        // if ($status == 2) {
        //     $where['status']=2;
        // }
        $where['status']=['in',['0','1']];
        $trademodel = new TradeModel();
        $orders = $trademodel->where('user_id',$this->auth->id)->where('tosymbol','<>','USDT')->where($where)->limit(10)->page(input('page/d',1))->select();
        // echo $trademodel->getLastSql();
        $this->success('返回成功',['list'=>$orders]);
    }

    /**
     * 我的交易详情
     * @ApiParams   (name="id", type="int", required=true, description="匹配订单详情")
     * @return [type] [description]
     */
    public function gettradelog()
    {
        $id = $this->request->request('id/d',0);
        if (!$id) {
            $this->error('订单id传入错误');
        }

        $tradelog = new Tradelog();

        $trade_log = $tradelog->where('buy_user_id|sell_user_id',$this->auth->id)->where('id',$id)->find();

        $this->success('返回成功',['info'=>$trade_log]);
    }

    /**
     * 获取交易场首页的挂买 挂卖订单
     * @return [type] [description]
     */
    public function getTradeHomeBuyAndSell()
    {
        $symbol = $this->request->request('symbol','');
        $tosymbol = $this->request->request('tosymbol','');
        if (!$symbol||!$symbol) {
            $this->error('违规操作');
        }
        $trademodel = new TradeModel();

        $sell = $trademodel
            ->where('symbol',$symbol)
            ->where('tosymbol',$tosymbol)
            ->where('tosymbol','<>','USDT')
            ->where('surplusnum','>',0)
            ->where('status','in',[0,1])
            ->where('user_id','<>',$this->auth->id)
            ->where('action','sell')
            ->limit(10)
            ->select();
        $buy = $trademodel
            ->where('symbol',$symbol)
            ->where('tosymbol',$tosymbol)
            ->where('tosymbol','<>','USDT')
            ->where('surplusnum','>',0)
            ->where('status','in',[0,1])
            ->where('user_id','<>',$this->auth->id)
            ->where('action','buy')
            ->limit(10)
            ->select();
        $buysymbol = db('coin')->where('symbol',$symbol)->field('id,name,symbol,exch_rate,describe')->find();
        $sellsymbol = db('coin')->where('symbol',$tosymbol)->field('id,name,symbol,exch_rate,describe')->find();

        $this->success('返回成功',['sell'=>$sell,'buy'=>$buy,'symbol'=>$buysymbol,'tosymbol'=>$sellsymbol]);
    }


    /**
     * 获取交易场上 挂卖或挂买订单
     * @param string $action 查询挂卖或挂买  buy or sell
     * @return [type] [description]
     */
    public function getTradeList()
    {
        $page = $this->request->request('page/d',1);
        $action = $this->request->request('action','');
        if (!in_array($action, ['buy','sell'])) {
            $this->error('查询异常，buy or sell');
        }
        $trademodel = new TradeModel();
        $trades = $trademodel
            ->where('tosymbol','<>','USDT')
            ->where('surplus','>',0)
            ->where('status','in',[0,1])
            ->where('user_id','<>',$this->auth->id)
            ->where('action',$action)
            ->page($page)
            ->limit(10)
            ->select();
        $this->error('返回成功',['list'=>$trades]);
    }

    /**
     * 交易订单明细
     * @param int $id 订单id
     * @return [type] [description]
     */
    public function tradeorderinfo()
    {
        $id = $this->request->request('id/d',0);
        if (!$id) {
            $this->error('订单id传入错误');
        }
        $trademodel = new TradeModel();
        $order = $trademodel->where('user_id',$this->auth->id)->where('id',$id)->find();
        $user_id = $this->auth->id;
        $userpay = Hook::listen("get_userpay",$user_id);
        $order->pay = $userpay[0];
        if (!$order) {
            $this->error('订单被外星人劫持');
        }

        $tradelog = new Tradelog();
        $step1 =  config('site.trade_dispute_time_step1');
        $step2 =  config('site.trade_dispute_time_step2');
        switch ($order->action) {
            case 'sell':
                $tradelogs = $tradelog->where('sell_trade_id',$order->id)->select();

                foreach ($tradelogs as &$log) {
                    $buy_user_id = $log->buy_user_id;
                    $buyuserpay  = Hook::listen("get_userpay",$buy_user_id);
                    $log->buyuserpay = $buyuserpay;

                    if ($log->status == 'waitting' && ($log->createtime + $step1*60 < time())) {
                        $log->allowdispute = 1;
                    }elseif($log->status == 'affirm'){
                        $log->allowdispute = 1;
                    }else{
                        $log->allowdispute = 0;
                    }
                }
                

                $order->tradelogs   =$tradelogs;
                break;
            case 'buy':
                $tradelogs = $tradelog->where('buy_trade_id',$order->id)->select();
                foreach ($tradelogs as &$log) {
                    $sell_user_id = $log->sell_user_id;
                    $selluserpay  = Hook::listen("get_userpay",$sell_user_id);
                    $log->buyuserpay = $selluserpay;

                    if ($log->status == 'waitting' && ($log->createtime + $step1*60 < time())) {
                        $log->allowdispute = 0;
                    }elseif($log->status == 'affirm' && ($log->updatetime + $step2*60 < time()) ){
                        $log->allowdispute = 1;
                    }else{
                        $log->allowdispute = 0;
                    }
                }
                $order->tradelogs = $tradelogs;
                break;
            default:
                $this->error('您的订单数据异常，被外星人篡改了');
                break;
        }

        $this->success('返回成功',['info'=>$order]);
    }

    /**
     * 确认打款
     * @param int $id 订单id
     * @return [type] [description]
     */
    public function comfirmdakuan()
    {
        $id = $this->request->request('id/d',0);
        $voucher = $this->request->request('voucher/s',0);
        if (!$id) {
            $this->error('订单id传入错误');
        }
        // if (!$voucher) {
        //     $this->error('请上传凭证');
        // }
        // $trademodel = new TradeModel();
        // $order = $trademodel->where('user_id',$this->auth->id)->where('id',$id)->find();
        // if (!$order) {
        //     $this->error('订单被外星人劫持');
        // }

        $tradelog = new Tradelog();

        $order = $tradelog->where('buy_user_id',$this->auth->id)->where('id',$id)->find();

        if (!$order) {
            $this->error('订单被外星人劫持');
        }
        // echo $order->status;
        if ($order->status != 'waitting') {
            $this->error('订单状态不正确',['order'=>$order]);
        }
        $tradelog->save(['status'=>'affirm'],['id'=>$id]);
        
        $sell_user_id = $order['sell_user_id'];

        $userpay = Hook::listen("get_userpay",$sell_user_id);
        $config  = get_addon_config('clsms');
        $event = $config['event'];
        if (isset($event['comfirm'])) {
            $str = $event['comfirm'];
        }
        else {
            return false;
        }
        $str = str_replace('{tradeno}',$order['trade_no'],$str);
        $str = str_replace('{symbol}',$order['symbol'],$str);
        $msg = str_replace('{num}',$order['buy_num'],$str);
        if ($userpay[0]['mobile']) {
            Smslib::notice($userpay[0]['mobile'],$msg);
        }

        $this->success('确认打款',['info'=>$order]);
    }

    /**
     * 确认收款
     * @param int $id 订单id
     * @return [type] [description]
     */
    public function comfirmshoukuan()
    {
        $id = $this->request->request('id/d',0);
        if (!$id) {
            $this->error('订单id传入错误');
        }
        // $trademodel = new TradeModel();
        // $order = $trademodel->where('user_id',$this->auth->id)->where('id',$id)->find();
        // if (!$order) {
        //     $this->error('订单被外星人劫持');
        // }

        $tradelog = new Tradelog();

        $order = $tradelog->where('sell_user_id',$this->auth->id)->where('id',$id)->find();

        if (!$order) {
            $this->error('订单被外星人劫持');
        }
        if ($order->status != 'affirm') {
            $this->error('订单状态不正确');
        }

        $tradelog->where('id',$id)->update(['status'=>'finish']);

        // $trademodel = new TradeModel();
        // $order = $trademodel->where('user_id',$buy_trade_id)->->find();
        $trademodel = new TradeModel();
        $runningtradebuy = $tradelog->where('buy_trade_id',$order->buy_trade_id)->where('status','in',['waitting','affirm','dispute'])->find();
        if (!$runningtradebuy) {
            $trademodel->where('id',$order->buy_trade_id)->update(['status'=>'2']);
        }
        $runningtradesell = $tradelog->where('sell_trade_id',$order->sell_trade_id)->where('status','in',['waitting','affirm','dispute'])->find();
        if (!$runningtradesell) {
            $trademodel->where('id',$order->sell_trade_id)->update(['status'=>'2']);
        }

        if ($order->symbol == 'USD' && $order->tosymbol == 'USDT') {
            User::tokenlog($order->symbol,$order->buy_user_id,0,$order->sell_num,'buy','买入到账');
        }
        if ($order->symbol == 'USD' && $order->tosymbol == 'FAE') {
            User::tokenlog($order->symbol,$order->buy_user_id,0,$order->sell_num,'buy','买入到账');
        }
        $this->success('确认收款',['info'=>$order]);
    }

    /**
     * 申请订单仲裁
     * @param int $id 订单id
     * @return [type] [description]
     */
    public function dispute()
    {
        $id = $this->request->request('id/d',0);
        if (!$id) {
            $this->error('订单id传入错误');
        }

        $tradelog = new Tradelog();

        $order = $tradelog->where('buy_user_id|sell_user_id',$this->auth->id)->where('id',$id)->find();

        if (!$order) {
            $this->error('订单被外星人劫持');
        }
        if ($order->status == 'waitting') {
            if($order->sell_user_id == $this->auth->id){
                $disputestatus =$order->status;
            }else{
                $this->error('您不能申请改订单的仲裁');
            }
            
        }elseif($order->status == 'affirm'){
            if ($order->buy_user_id == $this->auth->id) {
                $disputestatus =$order->status.'buy';
            }elseif($order->sell_user_id == $this->auth->id){
                $disputestatus =$order->status.'sell';
            }else{
                $this->error('订单被外星人劫持');
            }
        }else{
            $this->error('订单状态不允许申请仲裁');
        }
        $tradelog->save(['status'=>'dispute','disputestatus'=>$disputestatus],['id'=>$id]);
        $this->success('提交仲裁成功',['info'=>$order]);
    } 
}
